<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>多词查询 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/match-multi-word.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/match-multi-word.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/match-multi-word.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/match-multi-word.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="search-in-depth.html">深入搜索</a></span>
»
<span class="breadcrumb-link"><a href="full-text-search.html">全文搜索</a></span>
»
<span class="breadcrumb-node">多词查询</span>
</div>
<div class="navheader">
<span class="prev">
<a href="match-query.html">« 匹配查询</a>
</span>
<span class="next">
<a href="bool-query.html">组合查询 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="match-multi-word"></a>多词查询<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/100_Full_Text_Search/10_Multi_word_queries.asciidoc">edit</a>
</h2>
</div></div></div>
<p>如果我们一次只能搜索一个词，那么全文搜索就会不太灵活，幸运的是 <code class="literal">match</code> 查询让多词查询变得简单：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "BROWN DOG!"
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/100_Full_Text_Search/05_Match_query.json"></div>
<p>上面这个查询返回所有四个文档：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
  "hits": [
     {
        "_id":      "4",
        "_score":   0.73185337, <a id="CO58-1"></a><i class="conum" data-value="1"></i>
        "_source": {
           "title": "Brown fox brown dog"
        }
     },
     {
        "_id":      "2",
        "_score":   0.47486103, <a id="CO58-2"></a><i class="conum" data-value="2"></i>
        "_source": {
           "title": "The quick brown fox jumps over the lazy dog"
        }
     },
     {
        "_id":      "3",
        "_score":   0.47486103, <a id="CO58-3"></a><i class="conum" data-value="2"></i>
        "_source": {
           "title": "The quick brown fox jumps over the quick dog"
        }
     },
     {
        "_id":      "1",
        "_score":   0.11914785, <a id="CO58-4"></a><i class="conum" data-value="3"></i>
        "_source": {
           "title": "The quick brown fox"
        }
     }
  ]
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO58-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>文档 4 最相关，因为它包含词 <code class="literal">"brown"</code> 两次以及 <code class="literal">"dog"</code> 一次。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO58-2"><i class="conum" data-value="2"></i></a><a href="#CO58-3"></a></p>
</td>
<td align="left" valign="top">
<p>文档 2、3 同时包含 <code class="literal">brown</code> 和 <code class="literal">dog</code> 各一次，而且它们 <code class="literal">title</code> 字段的长度相同，所以具有相同的评分。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO58-4"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>文档 1 也能匹配，尽管它只有 <code class="literal">brown</code> 没有 <code class="literal">dog</code> 。</p>
</td>
</tr>
</table>
</div>
<p>因为 <code class="literal">match</code> 查询必须查找两个词（ <code class="literal">["brown","dog"]</code> ），它在内部实际上先执行两次 <code class="literal">term</code> 查询，然后将两次查询的结果合并作为最终结果输出。为了做到这点，它将两个 <code class="literal">term</code> 查询包入一个 <code class="literal">bool</code> 查询中，详细信息见 <a class="xref" href="bool-query.html" title="组合查询">布尔查询</a>。</p>
<p>以上示例告诉我们一个重要信息：即任何文档只要 <code class="literal">title</code> 字段里包含 <em>指定词项中的至少一个词</em> 就能匹配，被匹配的词项越多，文档就越相关。</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="match-improving-precision"></a>提高精度<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/100_Full_Text_Search/10_Multi_word_queries.asciidoc">edit</a>
</h3>
</div></div></div>
<p>用 <em>任意</em> 查询词项匹配文档可能会导致结果中出现不相关的长尾。这是种散弹式搜索。可能我们只想搜索包含 <em>所有</em> 词项的文档，也就是说，不去匹配 <code class="literal">brown OR dog</code> ，而通过匹配 <code class="literal">brown AND dog</code> 找到所有文档。</p>
<p><code class="literal">match</code> 查询还可以接受 <code class="literal">operator</code> 操作符作为输入参数，默认情况下该操作符是 <code class="literal">or</code> 。我们可以将它修改成 <code class="literal">and</code> 让所有指定词项都必须匹配：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": {      <a id="CO59-1"></a><i class="conum" data-value="1"></i>
                "query":    "BROWN DOG!",
                "operator": "and"
            }
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/100_Full_Text_Search/05_Match_query.json"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO59-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">match</code> 查询的结构需要做稍许调整才能使用 <code class="literal">operator</code> 操作符参数。</p>
</td>
</tr>
</table>
</div>
<p>这个查询可以把文档 1 排除在外，因为它只包含两个词项中的一个。</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="match-precision"></a>控制精度<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/100_Full_Text_Search/10_Multi_word_queries.asciidoc">edit</a>
</h3>
</div></div></div>
<p>在 <em>所有</em> 与 <em>任意</em> 间二选一有点过于非黑即白。如果用户给定 5 个查询词项，想查找只包含其中 4 个的文档，该如何处理？将 <code class="literal">operator</code> 操作符参数设置成 <code class="literal">and</code> 只会将此文档排除。</p>
<p>有时候这正是我们期望的，但在全文搜索的大多数应用场景下，我们既想包含那些可能相关的文档，同时又排除那些不太相关的。换句话说，我们想要处于中间某种结果。</p>
<p><code class="literal">match</code> 查询支持 <code class="literal">minimum_should_match</code> 最小匹配参数，这让我们可以指定必须匹配的词项数用来表示一个文档是否相关。我们可以将其设置为某个具体数字，更常用的做法是将其设置为一个百分数，因为我们无法控制用户搜索时输入的单词数量：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": {
        "query":                "quick brown dog",
        "minimum_should_match": "75%"
      }
    }
  }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/100_Full_Text_Search/05_Match_query.json"></div>
<p>当给定百分比的时候， <code class="literal">minimum_should_match</code> 会做合适的事情：在之前三词项的示例中， <code class="literal">75%</code> 会自动被截断成 <code class="literal">66.6%</code> ，即三个里面两个词。无论这个值设置成什么，至少包含一个词项的文档才会被认为是匹配的。</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>参数 <code class="literal">minimum_should_match</code> 的设置非常灵活，可以根据用户输入词项的数目应用不同的规则。完整的信息参考文档
<a href="https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html#query-dsl-minimum-should-match" class="ulink" target="_top">https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html#query-dsl-minimum-should-match</a></p>
</div>
</div>
<p>为了完全理解 <code class="literal">match</code> 是如何处理多词查询的，我们就需要查看如何使用 <code class="literal">bool</code> 查询将多个查询条件组合在一起。</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="match-query.html">« 匹配查询</a>
</span>
<span class="next">
<a href="bool-query.html">组合查询 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>